22 #define D(x) cout << #x " is " << x << endl
26 Returns true if point (x, y) lies inside (or in the border)
27 of box defined by points (x0, y0) and (x1, y1).
29 bool point_in_box(double x
, double y
,
30 double x0
, double y0
, double x1
, double y1
){
31 return min(x0
, x1
) <= x
&& x
<= max(x0
, x1
) && min(y0
, y1
) <= y
&& y
<= max(y0
, y1
);
35 Finds the intersection between two segments (Not infinite lines!)
36 Segment 1 goes from point (x0, y0) to (x1, y1).
37 Segment 2 goes from point (x2, y2) to (x3, y3).
39 Handles the case when the 2 segments are:
40 *Parallel but don't lie on the same line (No intersection)
41 *Parallel and both lie on the same line (Infinite intersections or no intersections)
42 *Not parallel (One intersection or no intersections)
44 Returns true if the segments do intersect in any case.
46 bool segment_segment_intersection(double x0
, double y0
, double x1
, double y1
,
47 double x2
, double y2
, double x3
, double y3
){
52 double t0
= (y3
-y2
)*(x0
-x2
)-(x3
-x2
)*(y0
-y2
);
53 double t1
= (x1
-x0
)*(y2
-y0
)-(y1
-y0
)*(x2
-x0
);
54 double det
= (y1
-y0
)*(x3
-x2
)-(y3
-y2
)*(x1
-x0
);
57 if (fabs(t0
) < EPS
|| fabs(t1
) < EPS
){
58 //they lie on same line, but they may or may not intersect.
59 return (point_in_box(x0
, y0
, x2
, y2
, x3
, y3
) ||
60 point_in_box(x1
, y1
, x2
, y2
, x3
, y3
) ||
61 point_in_box(x2
, y2
, x0
, y0
, x1
, y1
) ||
62 point_in_box(x3
, y3
, x0
, y0
, x1
, y1
));
64 //just parallel, no intersection
71 0 <= t0 <= 1 if the intersection point lies in segment 1.
72 0 <= t1 <= 1 if the intersection point lies in segment 2.
74 if (0.0 <= t0
&& t0
<= 1.0 && 0.0 <= t1
&& t1
<= 1.0){
75 double x
= x0
+ t0
*(x1
-x0
);
76 double y
= y0
+ t0
*(y1
-y0
);
77 //intersection is point (x, y)
80 //the intersection points doesn't lie on both segments.
85 typedef pair
<double, double> point
;
86 typedef pair
<point
, point
> segment
;
89 while (scanf("%d", &n
) && n
){
90 vector
<segment
> sticks
;
92 for (int i
=0; i
<n
; ++i
){
93 double x0
, y0
, x1
, y1
;
94 scanf("%lf %lf %lf %lf", &x0
, &y0
, &x1
, &y1
);
95 sticks
.push_back(segment(point(x0
, y0
), point(x1
, y1
)));
96 for (list
<int>::iterator j
= top
.begin(); j
!= top
.end(); ++j
){
97 const segment
&s
= sticks
[*j
];
98 bool b
= segment_segment_intersection(s
.first
.first
, s
.first
.second
,
99 s
.second
.first
, s
.second
.second
,
102 printf("Intersection between <(%.2lf, %.2lf) - (%.2lf, %.2lf)> and "
103 "<(%.2lf, %.2lf) - (%.2lf, %.2lf)> = %s\n", x0, y0, x1, y1,
104 s.first.first, s.first.second, s.second.first, s.second.second,
105 (b ? "true" : "false"));
108 if (b
) j
= top
.erase(j
), --j
;
112 printf("Top sticks:");
114 for (list
<int>::iterator i
= top
.begin(); k
< top
.size(); ++i
, ++k
){
115 printf(" %d%c", *i
+ 1, (k
< top
.size()-1 ? ',' : '.'));